using SFB;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using GeneratorConfig = ScriptGenerator.Config;

/// <summary>
/// UI 脚本变量声明定义生成
/// </summary>
public static partial class UIVariableGenerator
{

    public struct ComponentTypeName
    {
        public const string Button = "Button";
        public const string Toggle = "Toggle";
    }

    public class VariableData
    {
        public string ShortType;
        public string VariableName;
        public bool ContainExceptSign;
        public int Count => Tsfs.Count;
        public Transform Tsf;
        public List<Transform> Tsfs;

        public VariableData(string shortTypeName, string variableName, bool containExceptSign = false, Transform transform = null)
        {
            ShortType = shortTypeName;
            VariableName = variableName;
            ContainExceptSign = containExceptSign;
            Tsf = transform;
            Tsfs = new List<Transform>() { Tsf };
        }
    }

    private static string m_VariableNameRegex = @"^~?#(?<variableType>[A-Za-z0-9]+)_(?<variableName>[A-Za-z0-9]+)(|_(?<variableIndex>\d+))$";
    private static string m_ExceptSign = "~";

    private static Encoding m_Encoding = Encoding.UTF8;

    private static string m_ClassName;
    private static string m_VariableClassName;
    private static string m_Declarations;
    private static string m_Definitions;
    private static string m_PrefabPath;

    private static string m_ClickListeners;
    private static string m_ClickCallbacks;
    private static string m_ClickRemoveListeners;

    private static string m_DeclarationFormat = "\t\tpublic {0} {1};\n";
    //private static string m_GoNamePrefixFormat = "{0}#{1}_{2}";

    private static string m_Comment = "";

    // 如果前缀是SP, 则直接读取脚本
    private static string m_ScriptPre = "SP";
    // 如果前缀是HS, 则直接读取热更脚本的配置名称
    private static string m_HotfixScriptPre = "HS";
    private static string m_ReuseListPre = "RL";
    private static bool m_IsUIReuseItem = false;
    public static Dictionary<string, string> TypeMapping
    {
        get
        {
            EnsureTypeMappingLoaded();
            return m_TypeDict;
        }
    }

    private static Dictionary<string, string> m_TypeDict = null;
    private static UIVariableTypeMappingConfig m_TypeConfigAsset;

    private static void EnsureTypeMappingLoaded()
    {
        if (m_TypeConfigAsset == null)
        {
            // 查找项目中的配置资产
            string[] guids = AssetDatabase.FindAssets("t:UIVariableTypeMappingConfig");
            if (guids != null && guids.Length > 0)
            {
                string path = AssetDatabase.GUIDToAssetPath(guids[0]);
                m_TypeConfigAsset = AssetDatabase.LoadAssetAtPath<UIVariableTypeMappingConfig>(path);
            }
            else
            {
                // 没有找到资产则自动创建一个并写入默认映射
                string folder = "Assets/Scripts/Editor/ScriptGenerator/UIGenerator";
                if (!AssetDatabase.IsValidFolder("Assets/Scripts"))
                {
                    AssetDatabase.CreateFolder("Assets", "Scripts");
                }
                if (!AssetDatabase.IsValidFolder("Assets/Scripts/Editor"))
                {
                    AssetDatabase.CreateFolder("Assets/Scripts", "Editor");
                }
                if (!AssetDatabase.IsValidFolder("Assets/Scripts/Editor/ScriptGenerator"))
                {
                    AssetDatabase.CreateFolder("Assets/Scripts", "Editor");
                }
                if (!AssetDatabase.IsValidFolder("Assets/Scripts/Editor/ScriptGenerator/UIGenerator"))
                {
                    AssetDatabase.CreateFolder("Assets/Scripts/Editor/ScriptGenerator", "UIGenerator");
                }
                var asset = ScriptableObject.CreateInstance<UIVariableTypeMappingConfig>();
                asset.Entries = UIVariableTypeMappingConfig.GetDefaultEntries();
                string assetPath = Path.Combine(folder, "UIVariableTypeMapping.asset").Replace("\\", "/");
                AssetDatabase.CreateAsset(asset, assetPath);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
                m_TypeConfigAsset = asset;
            }
        }

        if (m_TypeConfigAsset != null)
        {
            // 如果资产存在但为空，则写入默认映射
            if (m_TypeConfigAsset.Entries == null || m_TypeConfigAsset.Entries.Count == 0)
            {
                m_TypeConfigAsset.Entries = UIVariableTypeMappingConfig.GetDefaultEntries();
                EditorUtility.SetDirty(m_TypeConfigAsset);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
            m_TypeDict = m_TypeConfigAsset.ToDictionary();
            return;
        }

        // 极端情况下兜底为空字典
        m_TypeDict = new Dictionary<string, string>();
    }

    [MenuItem("Tools/UI/创建UI变量类型映射配置")]
    private static void CreateUIVariableTypeMappingAsset()
    {
        // 目标路径（保持与当前脚本同目录）
        string folder = "Assets/Scripts/Editor/ScriptGenerator/UIGenerator";
        if (!AssetDatabase.IsValidFolder("Assets/Scripts"))
        {
            AssetDatabase.CreateFolder("Assets", "Scripts");
        }
        if (!AssetDatabase.IsValidFolder("Assets/Scripts/Editor"))
        {
            AssetDatabase.CreateFolder("Assets/Scripts", "Editor");
        }
        if (!AssetDatabase.IsValidFolder("Assets/Scripts/Editor/ScriptGenerator"))
        {
            AssetDatabase.CreateFolder("Assets/Scripts/Editor", "ScriptGenerator");
        }
        if (!AssetDatabase.IsValidFolder("Assets/Scripts/Editor/ScriptGenerator/UIGenerator"))
        {
            AssetDatabase.CreateFolder("Assets/Scripts/Editor/ScriptGenerator", "UIGenerator");
        }

        // 创建资产并填充当前映射
        var asset = ScriptableObject.CreateInstance<UIVariableTypeMappingConfig>();
        EnsureTypeMappingLoaded();
        foreach (var kv in m_TypeDict)
        {
            asset.Entries.Add(new UIVariableTypeMappingConfig.Entry { Key = kv.Key, FullType = kv.Value });
        }

        string assetPath = Path.Combine(folder, "UIVariableTypeMapping.asset").Replace("\\", "/");
        AssetDatabase.CreateAsset(asset, assetPath);
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        Selection.activeObject = asset;
        EditorGUIUtility.PingObject(asset);
        Debug.Log("已创建 UIVariableTypeMapping 配置资产于: " + assetPath);
    }

    private static Dictionary<string, string> m_CodeReplaceDict = new Dictionary<string, string>();

    private static Dictionary<string, VariableData> m_VariableArrayDict = new Dictionary<string, VariableData>();

    private static UIVariableHelper m_UIVariableHelper;

    [MenuItem("GameObject/生成UI脚本", priority = -10)]
    public static void GenerateVariableScript(MenuCommand menuCommand)
    {
        GameObject root = menuCommand.context as GameObject;
        //bool isUIForm = root.GetComponent<UGUIForm>() != null;
        bool isUIForm = root.CompareTag(Constant.Tag.UIForm);

        Init(menuCommand, isUIForm);

        var selectGameObject = Selection.activeGameObject;
        EditorSceneManager.MarkSceneDirty(selectGameObject.scene);

        DevelopManager.DevelopScriptableObject.GeneratorUIRoot = root;
        DevelopManager.DevelopScriptableObject.GeneratorClassName = m_ClassName;

		// 生成完立即安排一次延迟挂载（等脚本编译完成）
		EditorApplication.delayCall += TryAutoAttachAfterCompile;
    }

    private static void Init(MenuCommand menuCommand, bool isUIForm = false)
    {
        m_CodeReplaceDict.Clear();
        m_VariableArrayDict.Clear();
        m_ClassName = "";
        m_Declarations = "";
        m_Definitions = "";
        m_ClickListeners = "";
        m_ClickCallbacks = "";
        m_ClickRemoveListeners = "";
        m_Comment = "";
        m_PrefabPath = "";

        UnityEngine.GameObject root = menuCommand.context as UnityEngine.GameObject;
        
        // 检测是否是 UIReuseItem
        m_IsUIReuseItem = root.GetComponent<UIReuseItem>() != null;
        
        m_UIVariableHelper = root.GetOrAddComponent<UIVariableHelper>();
        m_UIVariableHelper.Variables = new List<GameObject>();

        m_ClassName = root.name;

        m_PrefabPath = PrefabStageUtility.GetPrefabStage(root)?.assetPath;

        if (new Regex(m_VariableNameRegex).IsMatch(m_ClassName))
        {
            Match nameMatch = new Regex(m_VariableNameRegex).Match(m_ClassName);
            string variableType = nameMatch.Groups["variableType"].Value;
            m_ClassName = GetRootFullTypeName(variableType, root);
        }
        else
        {
            GameMonoBehaviour hotfixMonoBehaviour = root.GetComponent<GameMonoBehaviour>();
            if (hotfixMonoBehaviour != null)
                m_ClassName = hotfixMonoBehaviour.GameMonoBehaviourName;

            if (m_ClassName.IsNullOrEmpty())
            {
                ScriptHelper scriptHelper = root.GetComponent<ScriptHelper>();
                if (scriptHelper != null)
                    m_ClassName = scriptHelper.ScriptName;
            }
        }

        m_VariableClassName = m_ClassName + ".Variable";

        ForeachTrans(root.transform);
        GenerateArrayCode();
        GenerateComment();
        ReplaceCode();

        if (m_IsUIReuseItem)
        {
            GenerateUIReuseItemVariableScript();
        }
        else if (isUIForm)
        {
            GenerateUIFormAndVariableScript();
        }
        else
        {
            GenerateUIVariableScript();
        }
    }

    private static string GetRootFullTypeName(string variableType, GameObject root)
    {
        EnsureTypeMappingLoaded();
        if (m_TypeDict.ContainsKey(variableType))
        {
            return m_TypeDict[variableType];
        }

        //if (m_ReuseListPre.Equals(variableType))
        //{
        //    return typeof(IUIReuseList).Name;
        //}
         if (m_ScriptPre.Equals(variableType))
        {
            ScriptHelper scriptHelper = root.GetComponent<ScriptHelper>();
            if (scriptHelper != null)
                return scriptHelper.ScriptName;
            GameMonoBehaviour gameMonoBehaviour = root.GetComponent<GameMonoBehaviour>();
            Logger.Log(gameMonoBehaviour);
            if (gameMonoBehaviour != null)
                variableType = gameMonoBehaviour.GameMonoBehaviourName;
        }

        if (m_HotfixScriptPre.Equals(variableType))
        {
            GameMonoBehaviour hotfixMonoBehaviour = root.GetComponent<GameMonoBehaviour>();
            if (hotfixMonoBehaviour != null)
                variableType = hotfixMonoBehaviour.GameMonoBehaviourName;
        }
        return variableType;
    }

    /// <summary>
    /// 遍历需要生成代码的 UI Transform
    /// </summary>
    /// <param name="transform"></param>
    public static void ForeachTrans(Transform transform)
    {
        for (int i = 0; i < transform.childCount; i++)
        {
            Transform child = transform.GetChild(i);

            if (child.name.StartsWith(m_ExceptSign))
            {
                GenerateCode(child);
                continue;
            }

            GenerateCode(child);

            if (child.childCount > 0)
            {
                ForeachTrans(child);
            }
        }
    }

    private static void GenerateCode(Transform transform)
    {
        if (new Regex(m_VariableNameRegex).IsMatch(transform.name))
        {
            Match nameMatch = new Regex(m_VariableNameRegex).Match(transform.name);

            string variableType = nameMatch.Groups["variableType"].Value;
            string variableName = nameMatch.Groups["variableName"].Value;
            string variableIndex = nameMatch.Groups["variableIndex"].Value;

            string fullTypeName = GetRootFullTypeName(variableType, transform.gameObject);
            string variableFullName = variableType + variableName;

            // 生成数组形式
            if (!string.IsNullOrEmpty(variableIndex))
            {
                VariableData variable = new VariableData(variableType, variableFullName, transform.name.Contains(m_ExceptSign), transform);
                RecordArrayCode(variable);
                return;
            }

            m_Declarations += string.Format(m_DeclarationFormat, fullTypeName, variableFullName);
            m_Definitions += string.Format("\t\t\t{0} = variables[{1}]", variableFullName, m_UIVariableHelper.Variables.Count);

            if (fullTypeName.Equals("GameObject"))
            {

            }
            else if (fullTypeName.Equals("Transform"))
            {
                m_Definitions += ".transform";
            }
            else if (variableType == m_ReuseListPre)
            {
                m_Definitions += string.Format(".GetComponent<{0}>()", fullTypeName);
            }
            else if (variableType == m_ScriptPre)
            {
                m_Definitions += string.Format(".GetGameComponent<{0}>()", fullTypeName);
            }
            else if (transform.GetComponent(fullTypeName) != null)
            {
                m_Definitions += string.Format(".GetComponent<{0}>()", fullTypeName);
            }
            else if (variableType == m_HotfixScriptPre)
            {
                m_Definitions += string.Format(".ForceGetHotfixMonoBehaviour<{0}>()", fullTypeName);
            }
            else
            {
                m_Definitions += string.Format(".GetHotfixComponent<{0}>()", fullTypeName);
            }
            m_Definitions += ";\n";

            m_UIVariableHelper.Variables.Add(transform.gameObject);

            switch (fullTypeName)
            {
                case ComponentTypeName.Button:
                    GenerateButton(variableFullName);
                    break;
            }
        }
    }

    private static void RecordArrayCode(VariableData variable)
    {
        if (m_VariableArrayDict.TryGetValue(variable.VariableName, out var value))
        {
            value.Tsfs.Add(variable.Tsf);
        }
        else
        {
            m_VariableArrayDict.Add(variable.VariableName, variable);
        }
    }

    private static void GenerateButton(string variableName)
    {
        if (m_IsUIReuseItem)
        {
            m_ClickListeners += string.Format("\t\t\t\tm_UI.{0}.onClick.AddListener(OnClick{1});\n", variableName, variableName);
            // 注意：lambda 表达式无法直接移除，但由于 Variable 实例会重新创建，不需要手动移除
        }
        else
        {
            m_ClickListeners += string.Format("\t\t\t{0}.onClick.AddListener(script.OnClick{0});\n", variableName);
        }
        m_ClickCallbacks += "\tprivate void OnClick" + variableName + "()\n\t{\n\t}\n";
    }

    private static void GenerateArrayCode()
    {
        foreach (KeyValuePair<string, VariableData> kv in m_VariableArrayDict)
        {
            VariableData variable = kv.Value;

            string fullType = GetRootFullTypeName(variable.ShortType, variable.Tsf.gameObject);

            Debug.LogWarningFormat("{0}_{1}", variable.ShortType, fullType);

            m_Declarations += string.Format("\t\t\tpublic List<{0}> {1}s = new List<{2}>({3});\n", fullType, variable.VariableName, fullType, kv.Value.Count);

            m_Definitions += string.Format("\t\t\t\tfor ( int i = 0; i < {0}; i++)\n", variable.Count);
            m_Definitions += string.Format("\t\t\t\t\t{0}s.Add(variables[{1} + i]", variable.VariableName, m_UIVariableHelper.Variables.Count);

            if (fullType.Equals("GameObject"))
            {
            }
            else if (fullType.Equals("Transform"))
            {
                m_Definitions += ".transform";
            }
            else if (variable.ShortType == m_ReuseListPre)
            {
                m_Definitions += string.Format(".GetComponent<{0}>()", fullType);
            }
            else if (variable.ShortType == m_ScriptPre)
            {
                m_Definitions += string.Format(".GetGameComponent<{0}>()", fullType);
            }
            else if (variable.Tsf.GetComponent(fullType) != null)
            {
                m_Definitions += string.Format(".GetComponent<{0}>()", fullType);
            }
            else
            {
                m_Definitions += string.Format(".GetHotfixComponent<{0}>()", fullType);
            }
            m_Definitions += ");\n";


            switch (fullType)
            {
                case ComponentTypeName.Button:
                    GenerateButtonArray(variable);
                    break;
            }

            foreach (var tsf in variable.Tsfs)
            {
                m_UIVariableHelper.Variables.Add(tsf.gameObject);
            }
        }
    }

    private static void GenerateButtonArray(VariableData variable)
    {
        if (m_IsUIReuseItem)
        {
            string buttonListernerFormat = "\t\t\t\tfor ( int i = 0; i < m_UI.{0}s.Count; i++)\n" +
                                                   "\t\t\t\t{{\n" +
                                                   "\t\t\t\t\tint index = i + 1;\n" +
                                                   "\t\t\t\t\tm_UI.{1}s[i].onClick.AddListener(() =>\n" +
                                                   "\t\t\t\t\t{{\n" +
                                                   "\t\t\t\t\t\tOnClick{2}(index);\n" +
                                                   "\t\t\t\t\t}});\n" +
                                                   "\t\t\t\t}}\n";

            m_ClickListeners += string.Format(buttonListernerFormat, variable.VariableName, variable.VariableName, variable.VariableName);

            // 注意：lambda 表达式无法直接移除，但由于 Variable 实例会重新创建，不需要手动移除
        }
        else
        {
            string buttonListernerFormat = "\t\t\tfor ( int i = 0; i < {0}s.Count; i++)\n" +
                                                   "\t\t\t{{\n" +
                                                   "\t\t\t\tint index = i + 1;\n" +
                                                   "\t\t\t\t{1}s[i].onClick.AddListener(() =>\n" +
                                                   "\t\t\t\t{{\n" +
                                                   "\t\t\t\t\tscript.OnClick{2}(index);\n" +
                                                   "\t\t\t\t}});\n" +
                                                   "\t\t\t}}\n";

            m_ClickListeners += string.Format(buttonListernerFormat, variable.VariableName, variable.VariableName, variable.VariableName);
        }

        string buttonCallbackFormat = "\t\tpublic void OnClick{0}(int index)\n\t\t{{\n\t\t}}\n";

        m_ClickCallbacks += string.Format(buttonCallbackFormat, variable.VariableName);
    }

    private static void GenerateComment()
    {
        m_Comment += "/*\n" + m_ClickCallbacks + "\n*/";
    }

    public static void ReplaceCode()
    {
        m_CodeReplaceDict.Add("__Comment__", m_Comment);
        m_CodeReplaceDict.Add("__Class_Name__", m_ClassName);
        m_CodeReplaceDict.Add("__Variable_Declaration__", m_Declarations);
        m_CodeReplaceDict.Add("__Variable_Definition__", m_Definitions);
        m_CodeReplaceDict.Add("__Variable_ButtonListener__", m_ClickListeners);
        m_CodeReplaceDict.Add("__Variable_ButtonRemoveListener__", m_ClickRemoveListeners);
    }

    private static void GenerateUIFormAndVariableScript()
    {
        string outputDirectory = GeneratorConfig.UIFormDirectory + m_ClassName + "/";

        if (!Directory.Exists(outputDirectory))
        {
            //创建目录，同时生成XXUIForm.cs
            Directory.CreateDirectory(outputDirectory);
        }

        GenerateUIFormVariableScript();

        // 强制不覆盖，避免误操作
        if (!File.Exists(outputDirectory + m_ClassName + ".cs"))
        {
            GenerateUIFormScript();
        }
    }

    private static void GenerateUIFormScript()
    {
        string outputDirectory = GeneratorConfig.UIFormDirectory + m_ClassName + "/";

        string uiformPath = outputDirectory + m_ClassName + ".cs";

        Dictionary<string, string> CodeReplacement = new Dictionary<string, string>()
        {
            ["__Name__"] = m_ClassName,
            ["__Variable_ButtonCallback__"] = m_ClickCallbacks
        };

        TemplateScriptGenerator.GenerateScriptFile(GeneratorConfig.UIFormCodeTemplateFileName, uiformPath, CodeReplacement, Encoding.UTF8);
    }

    private static void GenerateUIFormVariableScript()
    {
        string outputFile = GeneratorConfig.UIVariableDirectory + m_ClassName + ".Variable.cs";
        TemplateScriptGenerator.GenerateScriptFile(GeneratorConfig.UIVariableCodeTemplateFileName, outputFile, m_CodeReplaceDict, m_Encoding);

        Logger.Log(string.Format("{0} 脚本生成成功", Utility.RichText.FormatColor(m_ClassName + ".Variable.cs", Constant.Color.GREEN)));
    }

    private static void GenerateUIReuseItemVariableScript()
    {
        // UIReuseItem 的 Variable 文件生成到 UIReuseItems 目录
        string outputDirectory = "Assets/Scripts/UIReuseItems/" + m_ClassName + "/";
        if (!Directory.Exists(outputDirectory))
        {
            Directory.CreateDirectory(outputDirectory);
        }
        
        // 生成 Variable.cs 文件（包含变量绑定和基础生命周期方法）
        string variableFile = outputDirectory + m_ClassName + ".Variable.cs";
        TemplateScriptGenerator.GenerateScriptFile(GeneratorConfig.UIReuseItemVariableCodeTemplateFileName, variableFile, m_CodeReplaceDict, m_Encoding);

        // 生成主类文件（可选，如果不存在则创建，用于编写自定义逻辑）
        string mainFile = outputDirectory + m_ClassName + ".cs";
        if (!File.Exists(mainFile))
        {
            Dictionary<string, string> mainCodeReplacement = new Dictionary<string, string>()
            {
                ["__Class_Name__"] = m_ClassName
            };
            TemplateScriptGenerator.GenerateScriptFile(GeneratorConfig.UIReuseItemCtrlCodeTemplateFileName, mainFile, mainCodeReplacement, m_Encoding);
        }

        Logger.Log(string.Format("{0} 脚本生成成功", Utility.RichText.FormatColor(m_ClassName + ".Variable.cs", Constant.Color.GREEN)));
    }

    public static void AddUIFormScript()
    {
        if (DevelopManager.DevelopScriptableObject.GeneratorUIRoot == null)
            return;

        var root = DevelopManager.DevelopScriptableObject.GeneratorUIRoot;
        // 对于非UIForm标签的预制体，使用保存的类名而不是root.name
        string className = DevelopManager.DevelopScriptableObject.GeneratorClassName;
        if (string.IsNullOrEmpty(className))
        {
            className = root.name;
        }
        
        // 检测是否是 UIReuseItem
        bool isUIReuseItem = root.GetComponent<UIReuseItem>() != null;
        
        // 调试日志：输出查找的类名
        Logger.Log($"AddUIFormScript - root.name: {root.name}, GeneratorClassName: {DevelopManager.DevelopScriptableObject.GeneratorClassName}, 查找类名: {className}, isUIReuseItem: {isUIReuseItem}");
        
        Type type = null;
        
        // 首先尝试从 Game 程序集中查找
        try
        {
            Assembly assembly = Assembly.Load(Config.Default.GameAssemblyName);
            
            // 先尝试完整类型名查找
            type = assembly.GetType(className);
            
            // 如果找不到，尝试在该程序集的所有类型中搜索（按名称匹配）
            if (type == null)
            {
                var allTypes = assembly.GetTypes();
                var matchingTypes = allTypes.Where(t => 
                    t.Name == className && 
                    typeof(Component).IsAssignableFrom(t) &&
                    (isUIReuseItem ? typeof(UIReuseItemCtrl).IsAssignableFrom(t) : typeof(GameMonoBehaviour).IsAssignableFrom(t))
                ).ToList();
                
                if (matchingTypes.Count > 0)
                {
                    type = matchingTypes[0];
                    Logger.Log($"从 Game 程序集中找到类型: {type.FullName} (使用名称匹配)");
                }
                else
                {
                    // 输出调试信息：列出所有匹配名称的类型
                    var allMatchingNames = allTypes.Where(t => t.Name == className).Select(t => $"{t.FullName} (基类: {t.BaseType?.Name ?? "null"})").ToList();
                    if (allMatchingNames.Count > 0)
                    {
                        Logger.LogWarning($"找到同名类型但基类不匹配: {string.Join(", ", allMatchingNames)}");
                    }
                }
            }
            else
            {
                Logger.Log($"从 Game 程序集中找到类型: {type.FullName}");
            }
        }
        catch (Exception e)
        {
            Logger.LogWarning($"加载程序集 {Config.Default.GameAssemblyName} 失败: {e.Message}");
        }
        
        // 如果还是找不到，尝试从所有已加载的程序集中查找（排除 Unity 引擎程序集）
        if (type == null)
        {
            // 根据是否是 UIReuseItem 选择优先查找的基类
            Type preferredBaseType = isUIReuseItem ? typeof(UIReuseItemCtrl) : typeof(GameMonoBehaviour);
            string preferredBaseTypeName = isUIReuseItem ? "UIReuseItemCtrl" : "GameMonoBehaviour";
            
            Type bestMatch = null;
            List<Type> allMatches = new List<Type>();
            
            foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies())
            {
                try
                {
                    var assemblyName = assembly.GetName().Name;
                    
                    // 跳过 Unity 引擎程序集，避免找到错误的类型（如 UnityEngine.UIElements.Panel）
                    if (assemblyName.StartsWith("UnityEngine") || 
                        assemblyName.StartsWith("UnityEditor") ||
                        assemblyName.StartsWith("Unity.") ||
                        assemblyName == "mscorlib" ||
                        assemblyName.StartsWith("System"))
                    {
                        continue;
                    }
                    
                    type = assembly.GetType(className);
                    if (type != null && typeof(Component).IsAssignableFrom(type))
                    {
                        // 优先选择继承自 preferredBaseType 的类型
                        if (preferredBaseType.IsAssignableFrom(type))
                        {
                            bestMatch = type;
                            Logger.Log($"从程序集 {assemblyName} 中找到类型: {type.FullName} (继承自 {preferredBaseTypeName})");
                            break;
                        }
                        allMatches.Add(type);
                    }
                    
                    // 尝试按名称匹配
                    var allTypes = assembly.GetTypes();
                    var matchingTypes = allTypes.Where(t => 
                        t.Name == className && 
                        typeof(Component).IsAssignableFrom(t) &&
                        !t.FullName.StartsWith("UnityEngine.") &&
                        !t.FullName.StartsWith("UnityEditor.")).ToList();
                    
                    foreach (var matchType in matchingTypes)
                    {
                        // 优先选择继承自 preferredBaseType 的类型
                        if (preferredBaseType.IsAssignableFrom(matchType))
                        {
                            bestMatch = matchType;
                            Logger.Log($"从程序集 {assemblyName} 中找到类型: {matchType.FullName} (使用名称匹配，继承自 {preferredBaseTypeName})");
                            break;
                        }
                        if (!allMatches.Contains(matchType))
                        {
                            allMatches.Add(matchType);
                        }
                    }
                    
                    if (bestMatch != null)
                    {
                        type = bestMatch;
                        break;
                    }
                }
                catch (Exception e)
                {
                    // 忽略无法访问的程序集
                    continue;
                }
            }
            
            // 如果没有找到继承自 preferredBaseType 的类型，使用第一个匹配的类型
            if (type == null && allMatches.Count > 0)
            {
                type = allMatches[0];
                Logger.Log($"从多个匹配中选择类型: {type.FullName} (共找到 {allMatches.Count} 个匹配)");
            }
        }

        if (type == null)
        {
            // 输出所有可用的类型名称（用于调试）
            try
            {
                Assembly assembly = Assembly.Load(Config.Default.GameAssemblyName);
                var allTypes = assembly.GetTypes();
                
                // 查找所有继承自 UIReuseItemCtrl 的类型（如果是 UIReuseItem）
                if (isUIReuseItem)
                {
                    var reuseItemTypes = allTypes.Where(t => 
                        typeof(UIReuseItemCtrl).IsAssignableFrom(t) && 
                        !t.IsAbstract && 
                        !t.IsInterface
                    ).Select(t => t.Name).Take(10).ToList();
                    Logger.Log($"可用的 UIReuseItemCtrl 类型: {string.Join(", ", reuseItemTypes)}");
                }
                
                // 查找包含类名的类型
                var matchingNameTypes = allTypes.Where(t => t.Name.Contains(className)).Select(t => $"{t.Name} (基类: {t.BaseType?.Name ?? "null"})").Take(10).ToList();
                if (matchingNameTypes.Count > 0)
                {
                    Logger.Log($"包含 '{className}' 的类型: {string.Join(", ", matchingNameTypes)}");
                }
            }
            catch (Exception e)
            {
                Logger.LogWarning($"获取调试信息失败: {e.Message}");
            }
            
            DevelopManager.DevelopScriptableObject.GeneratorUIRoot = null;
            DevelopManager.DevelopScriptableObject.GeneratorClassName = null;
            Logger.Log(string.Format("程序集 {0} 中不存在 {1} ，挂载失败。请确保脚本已编译完成。",
                Utility.RichText.FormatColor(Config.Default.GameAssemblyName, Constant.Color.RED),
                Utility.RichText.FormatColor(className + ".cs", Constant.Color.RED)));
            return;
        }

        // 验证类型是否是 Component 的子类，并且不是抽象类
        if (!typeof(Component).IsAssignableFrom(type))
        {
            DevelopManager.DevelopScriptableObject.GeneratorUIRoot = null;
            DevelopManager.DevelopScriptableObject.GeneratorClassName = null;
            Logger.Log(string.Format("类型 {0} 不是 Component 或 MonoBehaviour 的子类，无法挂载。类型信息: IsAbstract={1}, IsInterface={2}, BaseType={3}",
                Utility.RichText.FormatColor(type.FullName ?? type.Name, Constant.Color.RED),
                type.IsAbstract, type.IsInterface, type.BaseType?.Name ?? "null"));
            return;
        }

        if (type.IsAbstract)
        {
            DevelopManager.DevelopScriptableObject.GeneratorUIRoot = null;
            DevelopManager.DevelopScriptableObject.GeneratorClassName = null;
            Logger.Log(string.Format("类型 {0} 是抽象类，无法实例化挂载",
                Utility.RichText.FormatColor(type.FullName ?? type.Name, Constant.Color.RED)));
            return;
        }

        // 调试信息：输出找到的类型信息
        Logger.Log($"找到类型: {type.FullName ?? type.Name}, IsAbstract: {type.IsAbstract}, BaseType: {type.BaseType?.Name ?? "null"}");

        // 清理缺失的脚本引用，避免保存预制体时出错
        GameObjectUtility.RemoveMonoBehavioursWithMissingScript(root);
        
        // 使用泛型方法 GetComponent<T>() 更安全
        var getComponentMethod = typeof(GameObject).GetMethods()
            .First(m => m.Name == "GetComponent" && m.IsGenericMethod && m.GetParameters().Length == 0);
        var getComponentGeneric = getComponentMethod.MakeGenericMethod(type);
        
        Component existingComponent = null;
        try
        {
            existingComponent = getComponentGeneric.Invoke(root, null) as Component;
        }
        catch (Exception e)
        {
            Logger.LogError($"调用 GetComponent<{type.Name}>() 失败: {e.Message}\n类型: {type.FullName ?? type.Name}, IsComponent: {typeof(Component).IsAssignableFrom(type)}");
            DevelopManager.DevelopScriptableObject.GeneratorUIRoot = null;
            DevelopManager.DevelopScriptableObject.GeneratorClassName = null;
            return;
        }
        
        if (existingComponent != null)
        {
            DevelopManager.DevelopScriptableObject.GeneratorUIRoot = null;
            DevelopManager.DevelopScriptableObject.GeneratorClassName = null;
            Logger.Log(string.Format("预制体 {0} 已经挂载了 {1} 脚本",
                Utility.RichText.FormatColor(root.name, Constant.Color.GREEN),
                Utility.RichText.FormatColor(root.name + ".cs", Constant.Color.GREEN)));
            return;
        }
        
        // 使用泛型方法 AddComponent<T>() 更安全
        var addComponentMethod = typeof(GameObject).GetMethods()
            .First(m => m.Name == "AddComponent" && m.IsGenericMethod && m.GetParameters().Length == 0);
        var addComponentGeneric = addComponentMethod.MakeGenericMethod(type);
        
        try
        {
            addComponentGeneric.Invoke(root, null);
        }
        catch (Exception e)
        {
            Logger.LogError($"调用 AddComponent<{type.Name}>() 失败: {e.Message}\n类型: {type.FullName ?? type.Name}, IsComponent: {typeof(Component).IsAssignableFrom(type)}");
            DevelopManager.DevelopScriptableObject.GeneratorUIRoot = null;
            DevelopManager.DevelopScriptableObject.GeneratorClassName = null;
            return;
        }

        // 保留 ScriptHelper，避免后续仍需通过该组件记录脚本名时被移除
        // root.RemoveComponent<ScriptHelper>(true);

        var mono = root.GetComponent<GameMonoBehaviour>();
        if (mono != null)
        {
            mono.GameMonoBehaviourName = type.Name;
        }

        // 标记对象为脏，确保更改被保存
        EditorUtility.SetDirty(root);
        
        // 如果是预制体模式，需要保存预制体
        var prefabStage = PrefabStageUtility.GetPrefabStage(root);
        if (prefabStage != null)
        {
            // 在预制体编辑模式下，保存预制体
            PrefabUtility.SaveAsPrefabAsset(prefabStage.prefabContentsRoot, prefabStage.assetPath);
            prefabStage.ClearDirtiness();
            Logger.Log($"已保存预制体: {prefabStage.assetPath}");
        }
        else
        {
            // 如果不是预制体模式，检查是否是预制体实例
            var prefabAssetPath = PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(root);
            if (!string.IsNullOrEmpty(prefabAssetPath))
            {
                // 如果是预制体实例，需要应用更改到预制体
                PrefabUtility.ApplyPrefabInstance(root, InteractionMode.AutomatedAction);
                Logger.Log($"已应用更改到预制体: {prefabAssetPath}");
            }
        }
        
        // 刷新资源数据库，确保脚本引用正确
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();

        DevelopManager.DevelopScriptableObject.GeneratorUIRoot = null;
        DevelopManager.DevelopScriptableObject.GeneratorClassName = null;

        Logger.Log(string.Format("{0} 脚本挂载成功", Utility.RichText.FormatColor(root.name + ".cs", Constant.Color.GREEN)));
    }

	// 手动菜单，若自动挂载未触发可用此项补救
	[MenuItem("GameObject/挂载生成的UI脚本", priority = -9)]
	public static void AttachGeneratedUIScriptMenu()
	{
		AddUIFormScript();
	}

	// 编译/域重载后尝试自动挂载
	[InitializeOnLoadMethod]
	private static void OnEditorLoadedForUIVariableGenerator()
	{
		// 域重载完成后执行一次检查
		EditorApplication.delayCall += TryAutoAttachAfterCompile;
	}

	private static void TryAutoAttachAfterCompile()
	{
		// 若缓存了需要挂载的预制体，则尝试挂载
		if (DevelopManager.DevelopScriptableObject != null &&
			DevelopManager.DevelopScriptableObject.GeneratorUIRoot != null)
		{
			// 检查是否正在编译
			if (EditorApplication.isCompiling)
			{
				// 如果正在编译，延迟重试
				EditorApplication.delayCall += TryAutoAttachAfterCompile;
				return;
			}
			
			// 延迟一下，确保编译完成
			EditorApplication.delayCall += () =>
			{
				// 再次检查是否正在编译
				if (EditorApplication.isCompiling)
				{
					// 如果还在编译，再次延迟
					EditorApplication.delayCall += TryAutoAttachAfterCompile;
					return;
				}
				
				if (DevelopManager.DevelopScriptableObject != null &&
					DevelopManager.DevelopScriptableObject.GeneratorUIRoot != null)
				{
					AddUIFormScript();
				}
			};
		}
	}

    private static void GenerateUIVariableScript()
    {
        var cPath = GenerateUIScriptDic();
        // 将相对路径转换为绝对路径
        string absolutePath = cPath;
        if (!System.IO.Path.IsPathRooted(cPath))
        {
            // 如果是相对路径（以 Assets/ 开头），转换为绝对路径
            if (cPath.StartsWith("Assets/"))
            {
                absolutePath = System.IO.Path.Combine(Application.dataPath, "..", cPath).Replace("\\", "/");
            }
            else
            {
                absolutePath = System.IO.Path.Combine(Application.dataPath, "..", GeneratorConfig.UIFormDirectory, cPath).Replace("\\", "/");
            }
        }
        // 调试日志：输出路径信息
        Logger.Log($"GenerateUIVariableScript - m_PrefabPath: {m_PrefabPath}, cPath: {cPath}, absolutePath: {absolutePath}");
        StandaloneFileBrowser.SaveFilePanelAsync("保存的窗口", absolutePath, m_ClassName, "cs", (path) =>
        {
            if (!string.IsNullOrEmpty(path))
            {
                //强制不覆盖，避免误操作
                if (!File.Exists(path))
                {
                    Dictionary<string, string> CodeReplacement = new Dictionary<string, string>()
                    {
                        ["__Name__"] = m_ClassName,
                        ["__Variable_ButtonCallback__"] = m_ClickCallbacks
                    };

                    TemplateScriptGenerator.GenerateScriptFile(GeneratorConfig.UITemplateFileName, path, CodeReplacement, m_Encoding);
                }
            }
            string variableFilePath = GeneratorConfig.UIVariableDirectory + m_VariableClassName + ".cs";
            TemplateScriptGenerator.GenerateScriptFile(GeneratorConfig.UIVariableCodeTemplateFileName, variableFilePath, m_CodeReplaceDict, m_Encoding);

            Logger.Log(string.Format("{0} 脚本生成成功", Utility.RichText.FormatColor(m_VariableClassName + ".cs", Constant.Color.GREEN)));
        });
    }
    private const string PREFABBASE = "Prefabs/UIForms/";
    private const string PREFABBASE_ALT = "Prefabs/";
    private static string GenerateUIScriptDic()
    {
        //创建非formUI的c#脚本路径
        try
        {
            if (string.IsNullOrEmpty(m_PrefabPath))
            {
                return GeneratorConfig.UIFormDirectory;
            }

            // 统一路径格式，使用正斜杠
            string normalizedPath = m_PrefabPath.Replace("\\", "/");
            
            // 先尝试查找 Prefabs/UIForms/
            var pIndex = normalizedPath.IndexOf(PREFABBASE);
            if (pIndex >= 0)
            {
                // 找到 Prefabs/UIForms/，使用原来的逻辑
                pIndex += PREFABBASE.Length;
                int lastSlashIndex = normalizedPath.LastIndexOf('/');
                var fixedPath = normalizedPath.Substring(0, lastSlashIndex + 1);
                var subPath = fixedPath.Substring(pIndex, fixedPath.Length - pIndex);
                var cDirPath = Path.Combine(GeneratorConfig.UIFormDirectory, subPath);
                if (!Directory.Exists(cDirPath))
                {
                    Directory.CreateDirectory(cDirPath);
                }
                return cDirPath;
            }
            else
            {
                // 如果找不到 Prefabs/UIForms/，尝试查找 Prefabs/
                pIndex = normalizedPath.IndexOf(PREFABBASE_ALT);
                if (pIndex >= 0)
                {
                    // 提取 Prefabs/ 之后的路径部分（去掉文件名）
                    pIndex += PREFABBASE_ALT.Length;
                    int lastSlashIndex = normalizedPath.LastIndexOf('/');
                    if (lastSlashIndex > pIndex)
                    {
                        // 提取子路径，例如：Prefabs/UI/CardSelectDialog/Panel.prefab -> UI/CardSelectDialog/
                        var subPath = normalizedPath.Substring(pIndex, lastSlashIndex - pIndex + 1);
                        
                        // 如果子路径以 UI/ 开头，去掉 UI/ 前缀（因为 UIForms 目录已经表示 UI 了）
                        if (subPath.StartsWith("UI/"))
                        {
                            subPath = subPath.Substring(3); // 去掉 "UI/"
                        }
                        
                        var cDirPath = Path.Combine(GeneratorConfig.UIFormDirectory, subPath.TrimEnd('/'));
                        if (!Directory.Exists(cDirPath))
                        {
                            Directory.CreateDirectory(cDirPath);
                        }
                        return cDirPath;
                    }
                    else
                    {
                        // 如果 Prefabs/ 后面直接就是文件名，使用预制体名称作为目录名
                        string prefabName = System.IO.Path.GetFileNameWithoutExtension(normalizedPath);
                        var cDirPath = Path.Combine(GeneratorConfig.UIFormDirectory, prefabName);
                        if (!Directory.Exists(cDirPath))
                        {
                            Directory.CreateDirectory(cDirPath);
                        }
                        return cDirPath;
                    }
                }
                else
                {
                    // 如果都找不到，使用预制体名称作为目录名
                    string prefabName = System.IO.Path.GetFileNameWithoutExtension(normalizedPath);
                    var cDirPath = Path.Combine(GeneratorConfig.UIFormDirectory, prefabName);
                    if (!Directory.Exists(cDirPath))
                    {
                        Directory.CreateDirectory(cDirPath);
                    }
                    return cDirPath;
                }
            }
        }
        catch (Exception e)
        {
            Debug.LogError($"GenerateUIScriptDic 错误: {e.Message}, m_PrefabPath: {m_PrefabPath}");
            return GeneratorConfig.UIFormDirectory;
        }
    }
}
